home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / p_aa4re / bb212src / bbover.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-02-16  |  12.8 KB  |  352 lines

  1. (*===========================================================================*)
  2. (* Overlay processor                                                         *)
  3. (*                                                                           *)
  4. (*   Copyright 1988, 1989, 1990, 1991 by H. Roy Engehausen.  All rights      *)
  5. (*   reserved.                                                               *)
  6. (*                                                                           *)
  7. (*===========================================================================*)
  8.  
  9. {$UNDEF  DEBUG}
  10. {$UNDEF  DEBUG_INIT} (* Debug initialize *)
  11.  
  12. UNIT BBOVER;
  13.  
  14. INTERFACE
  15.  
  16. TYPE
  17.   byte_ptr  = ^BYTE;
  18.  
  19. FUNCTION use_overlay(entry_point              : byte_ptr;
  20.                      time_to_wait_for_overlay : BYTE
  21.                                                     ) : BOOLEAN;
  22.  
  23. PROCEDURE free_overlay;
  24.  
  25. PROCEDURE overlay_save;
  26. PROCEDURE overlay_restore;
  27.  
  28. IMPLEMENTATION
  29.  
  30. USES
  31.   CRT,
  32.   OVERLAY,
  33.   bbbug,
  34.   bbdummy,
  35.   bbdump,
  36.   bbsema2,
  37.   bbstr,
  38.   bbtask,
  39.   bbtime,
  40.   bbwin;
  41.  
  42. (*===========================================================================*)
  43. (* Globals                                                                   *)
  44. (*===========================================================================*)
  45.  
  46. (*===========================================================================*)
  47. (* Use a certain overlay                                                     *)
  48. (*      Return true when we can use overlay                                  *)
  49. (*===========================================================================*)
  50.  
  51. FUNCTION use_overlay(entry_point              : byte_ptr;
  52.                      time_to_wait_for_overlay : BYTE
  53.                                                     ) : BOOLEAN;
  54.  
  55.   VAR
  56.     b        : BOOLEAN;
  57.     i        : BYTE;
  58.     s_type   : semaphore_type;       (* True when things are OK *)
  59.     time_out : LONGINT;
  60.  
  61.   BEGIN;
  62.  
  63.       use_overlay := TRUE;
  64.       EXIT;
  65.  
  66.   END;
  67.  
  68. (*===========================================================================*)
  69. (* Free an overlay                                                           *)
  70. (*===========================================================================*)
  71.  
  72. PROCEDURE free_overlay;
  73.  
  74.   BEGIN;
  75.  
  76.   END;
  77.  
  78. (*===========================================================================*)
  79. (* Overlay_save                                                              *)
  80. (*      Save info about overlay usage in the stack                           *)
  81. (*===========================================================================*)
  82.  
  83. PROCEDURE overlay_save;
  84.  
  85.   VAR
  86.     stack_frame_ptr : stack_frame_ptr_type;
  87.     over_head       : over_head_type;
  88.     found           : BOOLEAN;
  89.     work            : WORD;
  90.  
  91.     LABEL
  92.       inc_count_and_next_stack_item,
  93.       next_stack_item;
  94.  
  95.   BEGIN;
  96.  
  97.     (*-----------------------------------------------------------------------*)
  98.     (* Initialize things                                                     *)
  99.     (*-----------------------------------------------------------------------*)
  100.  
  101.     over_head.off := 0;
  102.  
  103.     (*-----------------------------------------------------------------------*)
  104.     (* Set the overlay fixup count to zero for now                           *)
  105.     (*-----------------------------------------------------------------------*)
  106.  
  107.     active_tcb^.tcb_ovr_cnt := 0;
  108.  
  109.     (*-----------------------------------------------------------------------*)
  110.     (* Get the current setting of BP                                         *)
  111.     (*-----------------------------------------------------------------------*)
  112.  
  113.     ASM;
  114.       MOV work,BP
  115.     END;
  116.     stack_frame_ptr.pnt := PTR(SSEG, work);
  117.  
  118.     (*-----------------------------------------------------------------------*)
  119.     (* Loop back thru the stack                                              *)
  120.     (*-----------------------------------------------------------------------*)
  121.  
  122.     REPEAT
  123.  
  124.       {$IFDEF DEBUG_1}
  125.         WRITELN('Save stack frame at ', bp);
  126.  
  127.         WRITELN(        stack_frame_ptr^.link_seg,
  128.                 ':',    stack_frame_ptr^.link_off,
  129.                 ' -- ', stack_frame_ptr^.next_bp);
  130.         DELAY(1000);
  131.       {$ENDIF}
  132.  
  133.       (*---------------------------------------------------------------------*)
  134.       (* See if in overlay buffer                                            *)
  135.       (*---------------------------------------------------------------------*)
  136.  
  137.       IF stack_frame_ptr.pnt^.link_seg >= OvrHeapOrg THEN
  138.         BEGIN;
  139.  
  140.           {$IFDEF DEBUG_1}
  141.             WRITELN('In buffer ', stack_frame_ptr.pnt^.link_seg, '/', OvrHeapOrg);
  142.           {$ENDIF}
  143.  
  144.           (*-----------------------------------------------------------------*)
  145.           (* Search overlay list looking for the right header                *)
  146.           (*-----------------------------------------------------------------*)
  147.  
  148.           over_head.seg := OvrLoadList;
  149.  
  150.           found := FALSE;
  151.           work  := stack_frame_ptr.pnt^.link_seg;
  152.           REPEAT
  153.             IF over_head.pnt^.load_segment = work THEN
  154.               found := TRUE
  155.             ELSE
  156.               over_head.seg := over_head.pnt^.load_list_next;
  157.           UNTIL found OR (over_head.seg = 0);
  158.  
  159.           (*-----------------------------------------------------------------*)
  160.           (* If we didn't find it then die                                   *)
  161.           (*-----------------------------------------------------------------*)
  162.  
  163.           IF NOT found THEN
  164.             BEGIN;
  165.               WRITELN('Overlay ptr bad --', w2x(stack_frame_ptr.pnt^.link_seg),
  166.                                        '/', w2x(OvrHeapOrg),
  167.                                        '@', p2x(stack_frame_ptr.pnt));
  168.               dump_hex(stack_frame_ptr.pnt^.link_ptr, 20);
  169.               dump_all;
  170.               HALT;
  171.             END;
  172.  
  173.           stack_frame_ptr.pnt^.link_seg := over_head.seg;
  174.  
  175.           (*-----------------------------------------------------------------*)
  176.           (* Go to next item in stack                                        *)
  177.           (*-----------------------------------------------------------------*)
  178.  
  179.           GOTO inc_count_and_next_stack_item;
  180.  
  181.         END;
  182.  
  183.       (*---------------------------------------------------------------------*)
  184.       (* See if the segment can be used as a pointer to an overlay header.   *)
  185.       (* If not go to next one                                               *)
  186.       (*---------------------------------------------------------------------*)
  187.  
  188.       over_head.seg := stack_frame_ptr.pnt^.link_seg;
  189.  
  190.       IF over_head.pnt^.return_int <> int3f THEN
  191.         GOTO next_stack_item;
  192.  
  193.       (*---------------------------------------------------------------------*)
  194.       (* If the link offset is zero then the link points to the INT $3F in   *)
  195.       (* the overlay header and we need to get the offset from the header.   *)
  196.       (* If not, then the offset is already in the stack                     *)
  197.       (*---------------------------------------------------------------------*)
  198.  
  199.       IF stack_frame_ptr.pnt^.link_off = 0 THEN
  200.         stack_frame_ptr.pnt^.link_off := over_head.pnt^.return_ofs;
  201.  
  202.       (*---------------------------------------------------------------------*)
  203.       (* Bump count of saved overlay info                                    *)
  204.       (*---------------------------------------------------------------------*)
  205.  
  206. inc_count_and_next_stack_item:
  207.  
  208.       INC(active_tcb^.tcb_ovr_cnt);
  209.  
  210.       (*---------------------------------------------------------------------*)
  211.       (* Chain down the stack                                                *)
  212.       (*---------------------------------------------------------------------*)
  213.  
  214. next_stack_item:
  215.  
  216.       stack_frame_ptr.off := stack_frame_ptr.pnt^.next_bp;
  217.  
  218.     UNTIL stack_frame_ptr.pnt^.next_bp = 0; (*----- End loop thru stack -----*)
  219.  
  220.   END;
  221.  
  222. (*===========================================================================*)
  223. (* Overlay_restore                                                           *)
  224. (*      Restore info about overlay usage into the stack                      *)
  225. (*===========================================================================*)
  226.  
  227. PROCEDURE overlay_restore;
  228.  
  229.   VAR
  230.     stack_frame_ptr : stack_frame_ptr_type;
  231.     over_head       : over_head_type;
  232.     found           : BOOLEAN;
  233.     down_count      : BYTE;
  234.     loop_count      : BYTE;
  235.     used_count      : BYTE;
  236.     overlay_used    : ARRAY[1..20] OF WORD;
  237.     work            : WORD;
  238.  
  239.     LABEL
  240.       found_it,
  241.       next_stack_item;
  242.  
  243.   BEGIN;
  244.  
  245.     over_head.off := 0;
  246.     used_count    := 0;
  247.  
  248.     down_count    := active_tcb^.tcb_ovr_cnt;
  249.  
  250.     (*-----------------------------------------------------------------------*)
  251.     (* Get the current setting of BP                                         *)
  252.     (*-----------------------------------------------------------------------*)
  253.  
  254.     ASM;
  255.       MOV work,BP
  256.     END;
  257.     stack_frame_ptr.pnt := PTR(SSEG, work);
  258.  
  259.     (*-----------------------------------------------------------------------*)
  260.     (* Loop back thru the stack                                              *)
  261.     (*-----------------------------------------------------------------------*)
  262.  
  263.     WHILE down_count > 0 DO
  264.       BEGIN;
  265.  
  266.         (*-------------------------------------------------------------------*)
  267.         (* See if the segment can be used as a pointer to an overlay header. *)
  268.         (* If not go to next one                                             *)
  269.         (*-------------------------------------------------------------------*)
  270.  
  271.         over_head.seg := stack_frame_ptr.pnt^.link_seg;
  272.  
  273.         IF over_head.pnt^.return_int <> int3f THEN
  274.           GOTO next_stack_item;
  275.  
  276.         DEC(down_count);
  277.  
  278.         (*-------------------------------------------------------------------*)
  279.         (* See if the module is in storage and not on probation.            *)
  280.         (*-------------------------------------------------------------------*)
  281.  
  282.         IF (over_head.pnt^.load_segment <> 0)
  283.                                  AND (over_head.pnt^.first_entry <> int3f) THEN
  284.           BEGIN;
  285.  
  286.             (*---------------------------------------------------------------*)
  287.             (* Module is in storage.  Put out the correct link info          *)
  288.             (*---------------------------------------------------------------*)
  289.  
  290.             stack_frame_ptr.pnt^.link_seg := over_head.pnt^.load_segment;
  291.  
  292.             (*---------------------------------------------------------------*)
  293.             (* Done with this stack frame                                    *)
  294.             (*---------------------------------------------------------------*)
  295.  
  296.             GOTO next_stack_item;
  297.  
  298.           END; (*----- End of fixup of in-storage overlay -------------------*)
  299.  
  300.         (*-------------------------------------------------------------------*)
  301.         (* Module is not currently loaded                                    *)
  302.         (*-------------------------------------------------------------------*)
  303.  
  304.         (*-------------------------------------------------------------------*)
  305.         (* Determine if we have already fixed up a reference to this module  *)
  306.         (*-------------------------------------------------------------------*)
  307.  
  308.         found := FALSE;
  309.         FOR loop_count := 1 TO used_count DO
  310.           IF over_head.seg = overlay_used[loop_count] THEN
  311.             BEGIN;
  312.               found := TRUE;
  313.               GOTO found_it;
  314.             END;
  315.  
  316. found_it:
  317.  
  318.         (*-------------------------------------------------------------------*)
  319.         (* If no previous reference then put the offset into the header and  *)
  320.         (* point the link to the INT $3F.  Save the fact that we did do this *)
  321.         (* module                                                            *)
  322.         (*-------------------------------------------------------------------*)
  323.  
  324.         IF NOT found THEN
  325.           BEGIN;
  326.             over_head.pnt^.return_ofs     := stack_frame_ptr.pnt^.link_off;
  327.             stack_frame_ptr.pnt^.link_off := 0;
  328.  
  329.             INC(used_count);
  330.             overlay_used[used_count] := over_head.seg;
  331.           END;
  332.  
  333.         (*-------------------------------------------------------------------*)
  334.         (* Chain down the stack                                              *)
  335.         (*-------------------------------------------------------------------*)
  336.  
  337. next_stack_item:
  338.  
  339.         stack_frame_ptr.off := stack_frame_ptr.pnt^.next_bp;
  340.  
  341.         IF stack_frame_ptr.off = 0 THEN
  342.           BEGIN;
  343.             WRITELN('Popped whole overlay stack');
  344.             HALT;
  345.           END;
  346.  
  347.       END;  (*----- End loop thru stack -------------------------------------*)
  348.  
  349.   END;
  350.  
  351. END.
  352.